//-----------------------------------------------------------------------------
//  Copyright (c) 2013 by HangZhou HenqgQiao Design Corporation. All rights reserved.
//
//  Project  : 
//  Module   : over sample the input data with 8-phases 311M clock
//  Parent   : 
//  Children : 
//
//  Description: 
//
//  Parameters:
//  Local Parameters:
//
//  Notes       : 
//
//  Multicycle and False Paths

module	FRM_DELMT1(
   input                         FRM_RESET,

   input                         FRM_RXCLK,
   input[7:0]                    LINF_IN_RXD,
   input                         LINF_IN_RXDEN,

   output reg[8:0]               DELMT1_OUT_FMCNT270,
   output reg[3:0]               DELMT1_OUT_FMCNT9,
   output[7:0]                   DELMT1_OUT_DATA,
   output                        DELMT1_OUT_DEN,
   output                        DELMT1_OUT_OOF
   );



reg[31:0]                        MATCH_PRVS_DATA;            // previous enabled data
reg[39:0]                        MATCH_VECTOR;
reg[7:0]                         MATCH_OUT_HIT;
reg[14:0]                        MATCH_OUT_DATA_VECTOR;
reg                              MATCH_OUT_DEN;

reg[3:0]                         DSELC_HIT_DECODE;
reg[2:0]                         DSELC_SECL;
reg[7:0]                         DSELC_OUT_DATA;
reg                              DSELC_OUT_HIT;
reg                              DSELC_OUT_DEN;

reg[1:0]                         FASC_FSM;
reg                              FASC_MISMATCH_F6, FASC_MISMATCH_28;
reg[1:0]                         FASC_MISMATCH_CNT;
reg                              FASC_OUT_OOF;




always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 )
      MATCH_VECTOR[39:0]                          <= 40'd0;
   else if (LINF_IN_RXDEN==1'b1)  begin
      MATCH_VECTOR[39:8]                          <= MATCH_VECTOR[31:0];
      MATCH_VECTOR[7:0]                           <= LINF_IN_RXD[7:0];
   end
end


always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 ) begin
      MATCH_OUT_HIT[7:0]                          <= 8'd0;
      MATCH_OUT_DATA_VECTOR[14:0]                 <= 15'd0;
      MATCH_OUT_DEN                               <= 1'b0;
   end
   else begin
      MATCH_OUT_DEN                               <= LINF_IN_RXDEN;
      MATCH_OUT_DATA_VECTOR[14:0]                 <= MATCH_VECTOR[31:17];
      MATCH_OUT_HIT[7]                            <= MATCH_VECTOR[39:8]==32'hf6f6_2828;
      MATCH_OUT_HIT[6]                            <= MATCH_VECTOR[38:7]==32'hf6f6_2828;
      MATCH_OUT_HIT[5]                            <= MATCH_VECTOR[37:6]==32'hf6f6_2828;
      MATCH_OUT_HIT[4]                            <= MATCH_VECTOR[36:5]==32'hf6f6_2828;
      MATCH_OUT_HIT[3]                            <= MATCH_VECTOR[35:4]==32'hf6f6_2828;
      MATCH_OUT_HIT[2]                            <= MATCH_VECTOR[34:3]==32'hf6f6_2828;
      MATCH_OUT_HIT[1]                            <= MATCH_VECTOR[33:2]==32'hf6f6_2828;
      MATCH_OUT_HIT[0]                            <= MATCH_VECTOR[32:1]==32'hf6f6_2828;
   end
end




always @( MATCH_OUT_HIT ) begin
   case (MATCH_OUT_HIT[7:0])
   8'h80 : DSELC_HIT_DECODE[3:0]                  <= 4'b1_111;
   8'h40 : DSELC_HIT_DECODE[3:0]                  <= 4'b1_110;
   8'h20 : DSELC_HIT_DECODE[3:0]                  <= 4'b1_101;
   8'h10 : DSELC_HIT_DECODE[3:0]                  <= 4'b1_100;
   8'h08 : DSELC_HIT_DECODE[3:0]                  <= 4'b1_011;
   8'h04 : DSELC_HIT_DECODE[3:0]                  <= 4'b1_010;
   8'h02 : DSELC_HIT_DECODE[3:0]                  <= 4'b1_001;
   8'h01 : DSELC_HIT_DECODE[3:0]                  <= 4'b1_000;
   default:DSELC_HIT_DECODE[3:0]                  <= 4'b0_000;
   endcase
end

always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 )
      DSELC_SECL[2:0]                             <= 3'd0;
   else begin
      if ( FASC_OUT_OOF==1'b1 && MATCH_OUT_HIT[7:0]!=8'd0)
         DSELC_SECL[2:0]                          <= DSELC_HIT_DECODE[2:0];
   end
end


always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 )
      DSELC_OUT_DATA[7:0]                         <= 8'd0;
   else begin
      case (DSELC_SECL[2:0])
      3'b111: DSELC_OUT_DATA[7:0]                 <= MATCH_OUT_DATA_VECTOR[14:7];
      3'b110: DSELC_OUT_DATA[7:0]                 <= MATCH_OUT_DATA_VECTOR[13:6];
      3'b101: DSELC_OUT_DATA[7:0]                 <= MATCH_OUT_DATA_VECTOR[12:5];
      3'b100: DSELC_OUT_DATA[7:0]                 <= MATCH_OUT_DATA_VECTOR[11:4];
      3'b011: DSELC_OUT_DATA[7:0]                 <= MATCH_OUT_DATA_VECTOR[10:3];
      3'b010: DSELC_OUT_DATA[7:0]                 <= MATCH_OUT_DATA_VECTOR[9:2];
      3'b001: DSELC_OUT_DATA[7:0]                 <= MATCH_OUT_DATA_VECTOR[8:1];
      3'b000: DSELC_OUT_DATA[7:0]                 <= MATCH_OUT_DATA_VECTOR[7:0];
      default:;
      endcase
   end
end
always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 ) begin
      DSELC_OUT_HIT                               <= 1'b0;
      DSELC_OUT_DEN                               <= 1'b0;
   end
   else begin
      DSELC_OUT_DEN                               <= MATCH_OUT_DEN;
      DSELC_OUT_HIT                               <= MATCH_OUT_HIT[7:0]!=8'd0 && FASC_OUT_OOF==1'b1;
   end
end


always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 )
      DELMT1_OUT_FMCNT270[8:0]                    <= 9'd0;
   else begin
      if ( DSELC_OUT_HIT==1'b1 && DSELC_OUT_DEN==1'b1 )
         DELMT1_OUT_FMCNT270[8:0]                 <= 9'd3;
      else if ( DSELC_OUT_DEN==1'b1 ) begin
         if ( DELMT1_OUT_FMCNT270[8:0]==9'd269 )
            DELMT1_OUT_FMCNT270[8:0]              <= 9'd0;
         else
            DELMT1_OUT_FMCNT270[8:0]              <= DELMT1_OUT_FMCNT270[8:0] +9'd1;
      end
   end
end
always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 )
      DELMT1_OUT_FMCNT9[3:0]                      <= 4'd0;
   else begin
      if ( DSELC_OUT_HIT==1'b1 && DSELC_OUT_DEN==1'b1 )
         DELMT1_OUT_FMCNT9[3:0]                   <= 4'd0;
      else if ( DELMT1_OUT_FMCNT270[8:0]==9'd269 && DSELC_OUT_DEN==1'b1 ) begin
         if ( DELMT1_OUT_FMCNT9[3:0]==4'd8 )
            DELMT1_OUT_FMCNT9[3:0]                <= 4'd0;
         else
            DELMT1_OUT_FMCNT9[3:0]                <= DELMT1_OUT_FMCNT9[3:0] +4'd1;
      end
   end
end
  assign DELMT1_OUT_DATA[7:0]    = DSELC_OUT_DATA[7:0];
  assign DELMT1_OUT_DEN          = DSELC_OUT_DEN;


always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 )
      FASC_FSM[1:0]                                 <= 2'd0;
   else begin
      case ( FASC_FSM[1:0] )
      2'b00: begin
         if ( DSELC_OUT_HIT==1'b1 && DSELC_OUT_DEN==1'b1 )
            FASC_FSM[1:0]                           <= 2'd1;
      end
      2'b01: begin
         if ( FASC_MISMATCH_CNT[1:0]==2'd3 )
            FASC_FSM[1:0]                           <= 2'd0;
      end
      default:;
      endcase
   end
end

always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 )
      FASC_MISMATCH_F6                              <= 1'b0;
   else begin
      if ( DELMT1_OUT_FMCNT270[8:0]==9'd269 && DELMT1_OUT_FMCNT9[3:0]==4'd8 && DSELC_OUT_DEN==1'b1 )
         FASC_MISMATCH_F6                           <= 1'b0;
      else if ( DELMT1_OUT_FMCNT270[8:0]==9'd0 && DELMT1_OUT_FMCNT9[3:0]==4'd0 && DSELC_OUT_DEN==1'b1 )
         FASC_MISMATCH_F6                           <= (DELMT1_OUT_DATA[7:0]!=8'hf6);
      else if ( DELMT1_OUT_FMCNT270[8:0]==9'd1 && DELMT1_OUT_FMCNT9[3:0]==4'd0 && DSELC_OUT_DEN==1'b1 )
         FASC_MISMATCH_F6                           <= (DELMT1_OUT_DATA[7:0]!=8'hf6);
      else if ( DELMT1_OUT_FMCNT270[8:0]==9'd2 && DELMT1_OUT_FMCNT9[3:0]==4'd0 && DSELC_OUT_DEN==1'b1 )
         FASC_MISMATCH_F6                           <= (DELMT1_OUT_DATA[7:0]!=8'hf6);
   end
end
always @( posedge FRM_RESET or posedge FRM_RXCLK) begin
   if ( FRM_RESET==1'b1 )
      FASC_MISMATCH_28                              <= 1'b0;
   else begin
      if ( DELMT1_OUT_FMCNT270[8:0]==9'd269 && DELMT1_OUT_FMCNT9[3:0]==4'd8 && DSELC_OUT_DEN==1'b1 )
         FASC_MISMATCH_28                           <= 1'b0;
      else if ( DELMT1_OUT_FMCNT270[8:0]==9'd3 && DELMT1_OUT_FMCNT9[3:0]==4'd0 && DSELC_OUT_DEN==1'b1 )
         FASC_MISMATCH_28                           <= (DELMT1_OUT_DATA[7:0]!=8'h28);
      else if ( DELMT1_OUT_FMCNT270[8:0]==9'd4 && DELMT1_OUT_FMCNT9[3:0]==4'd0 && DSELC_OUT_DEN==1'b1 )
         FASC_MISMATCH_28                           <= (DELMT1_OUT_DATA[7:0]!=8'h28);
      else if ( DELMT1_OUT_FMCNT270[8:0]==9'd5 && DELMT1_OUT_FMCNT9[3:0]==4'd0 && DSELC_OUT_DEN==1'b1 )
         FASC_MISMATCH_28                           <= (DELMT1_OUT_DATA[7:0]!=8'h28);
   end
end
always @( posedge FRM_RESET or posedge FRM_RXCLK ) begin
   if ( FRM_RESET==1'b1 )
      FASC_MISMATCH_CNT[1:0]                                 <= 2'd0;
   else begin
      if ( FASC_FSM[1:0]==2'b01 ) begin
         if ( DELMT1_OUT_FMCNT270[8:0]==9'd269 && DELMT1_OUT_FMCNT9[3:0]==4'd8 && DSELC_OUT_DEN==1'b1 ) begin
            if ( FASC_MISMATCH_F6==1'b1 || FASC_MISMATCH_28==1'b1 )
               FASC_MISMATCH_CNT[1:0]                        <= FASC_MISMATCH_CNT[1:0] +2'd1;
            else
               FASC_MISMATCH_CNT[1:0]                        <= 2'd0;
         end
      end
      else begin
               FASC_MISMATCH_CNT[1:0]                        <= 2'd0;
      end
   end
end

always @( posedge FRM_RESET or posedge FRM_RXCLK ) begin
   if ( FRM_RESET==1'b1 )
      FASC_OUT_OOF                                  <= 1'b0;
   else
      FASC_OUT_OOF                                  <= FASC_FSM[1:0]==2'b00;
end
  assign DELMT1_OUT_OOF   = FASC_OUT_OOF;

endmodule


